/*
 *                        _oo0oo_
 *                       o8888888o
 *                       88" . "88
 *                       (| -_- |)
 *                       0\  =  /0
 *                     ___/`---'\___
 *                   .' \\|     |// '.
 *                  / \\|||  :  |||// \
 *                 / _||||| -:- |||||- \
 *                |   | \\\  - /// |   |
 *                | \_|  ''\---/''  |_/ |
 *                \  .-\__  '-'  ___/-. /
 *              ___'. .'  /--.--\  `. .'___
 *           ."" '<  `.___\_<|>_/___.' >' "".
 *          | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *          \  \ `_.   \_ __\ /__ _/   .-` /  /
 *      =====`-.____`.___ \_____/___.-`___.-'=====
 *                        `=---='
 * 
 * 
 *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 
 *            佛祖保佑     永不宕机     永无BUG
 */

/*
 * @Author: 火红色祥云 809880192@qq.com
 * @Date: 2023-11-25 14:24:17
 * @LastEditors: 火红色祥云 809880192@qq.com
 * @LastEditTime: 2023-11-25 14:39:10
 * @FilePath: /imx6ull-app/101_gpio/export.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>

#define GPIO_PATH "/sys/class/gpio/gpio1/"
#define GPIO_PIN "value"

int running = 1;

void export_gpio() {
    int fd_export = open("/sys/class/gpio/export", O_WRONLY);
    if (fd_export == -1) {
        perror("Error opening export file");
        exit(EXIT_FAILURE);
    }

    // Export GPIO1
    if (write(fd_export, "1", 2) == -1) {
        perror("Error exporting GPIO1");
        exit(EXIT_FAILURE);
    }

    close(fd_export);
}

void configure_gpio_direction() {
    char path[50];
    snprintf(path, sizeof(path), "%sdirection", GPIO_PATH);

    int fd_direction = open(path, O_WRONLY);
    if (fd_direction == -1) {
        perror("Error opening direction file");
        exit(EXIT_FAILURE);
    }

    // Set GPIO1 as output
    if (write(fd_direction, "out", 4) == -1) {
        perror("Error setting GPIO direction");
        exit(EXIT_FAILURE);
    }

    close(fd_direction);
}

void set_gpio_value(int value) {
    char path[50];
    snprintf(path, sizeof(path), "%s%s", GPIO_PATH, GPIO_PIN);

    int fd_value = open(path, O_WRONLY);
    if (fd_value == -1) {
        perror("Error opening value file");
        exit(EXIT_FAILURE);
    }

    // Set GPIO value
    char buffer[2];
    snprintf(buffer, sizeof(buffer), "%d", value);
    if (write(fd_value, buffer, 2) == -1) {
        perror("Error setting GPIO value");
        exit(EXIT_FAILURE);
    }

    close(fd_value);
}

void unexport_gpio() {
    int fd_unexport = open("/sys/class/gpio/unexport", O_WRONLY);
    if (fd_unexport == -1) {
        perror("Error opening unexport file");
        exit(EXIT_FAILURE);
    }

    // Unexport GPIO1
    if (write(fd_unexport, "1", 2) == -1) {
        perror("Error unexporting GPIO1");
        exit(EXIT_FAILURE);
    }

    close(fd_unexport);
}

void handle_sigint(int __attribute__((unused)) sig) {
    running = 0;
}


int main() {
    // Handle Ctrl+C
    signal(SIGINT, handle_sigint);

    // Export GPIO
    export_gpio();

    // Configure GPIO direction
    configure_gpio_direction();

    // Toggle GPIO value every 0.5 seconds
    while (running) {
        set_gpio_value(1);  // Set high
        usleep(50000);     // Sleep for 0.5 seconds
        set_gpio_value(0);  // Set low
        usleep(50000);     // Sleep for 0.5 seconds
    }

    // Unexport GPIO when the program is terminated
    unexport_gpio();

    return 0;
}
